/*
 * Description: 任务栏卡死监听
 */
#include "common_header.h"
#include <thread>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <map>
#include <wct.h>

class TaskBarMonitor {
public:
    TaskBarMonitor() = default;
    ~TaskBarMonitor() = default;
    static TaskBarMonitor& GetInstance();
    void Init();
    void DeInit();
private:
    void MonitorTaskBarStuck();
    void InitTaskBarStuckEventParams();
    bool IsTaskBarStuck();
    bool ProcessHwndNotRespond(const DWORD time, const HWND hwnd);
    bool ExplorerWndNotRespond(const DWORD time, std::string& hwndName);
    HWND GetprocessWndHandle(const std::string& wndName);
    bool IsTaskbarProcessExist();
    HWND GetProcessWndOfTaskbar(HWND& handle);
    HWND GetNotificationAreaWndOfTaskbar(HWND& handle);
    HWND GetStartsWndOfTaskbar(HWND& handle);
    void GetDeskTopWindows(HWND& handle);
    void GetExplorerWaitChain();
    void GetWaitChain(DWORD procesId, std::map<std::string, std::string>& getWaitChain);
    bool GrantDebugPrivilege();
    bool PrintWaitChain(DWORD threadId, HWCT wctHandle, std::map<std::string, std::string>& getWaitChain);
    void NotifyTaskBarStuck2Agent();
private:
    std::thread taskbarStuckMonitorThread;
    bool stopMonitorFlag = false;
    std::mutex mtx;
    std::condition_variable cv;

    time_t stuckTime = 0; // 卡死或者进程退出的时间
    UINT32 stuckType = 0; // 卡死类型(0:初始值; 1:窗口无响应; 2:explorer进程连续hang; 4:explorer进程不存在)
    std::string waitChain = "";
    std::string windowsClassOfStuck = ""; // 卡死的窗口
    UINT32 windowsTypeOfStuck = 0; // 无响应的窗口类类型(1:任务栏；2：桌面窗口）
    std::vector<time_t> winHangVec;
};

